import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/**
 * La clase Spindle agrupa los datos que controlan el
 * movimiento y velocidad del husillo
 */
public class Spindle extends DataCategory
{
    public Spindle()
    {
    }
    public boolean initData(int id,int value)
    {
        if(id<=0x0F)
            switch(id)
            {
                case KbdCmdId.CmdId.SPINDLE:
                    switch(value)
                    {
                        case KbdCmdId.CmdValue.SPINDLE_NORMAL_ROTATION:
                        case KbdCmdId.CmdValue.SPINDLE_REVERSE_ROTATION:
                            spindleDir = Integer.valueOf(value);
                            break;
                        case KbdCmdId.CmdValue.SPINDLE_START:
                        case KbdCmdId.CmdValue.SPINDLE_STOP:
                            spindleMtn = Integer.valueOf(value-2);
                            break;
                        default:
                            return false;
                    }
                    return true;
                case KbdCmdId.CmdId.SPINDLE_SPEED:
                    spindleSpd = Integer.valueOf(value);
                    return true;
                case KbdCmdId.CmdId.SPINDLE_OVERRIDE:
                    spindleSpdO = Integer.valueOf(value);
                    return true;
                default:
                    return false;
            }
        else
            switch(id)
            {
                case MINIMUM_SPINDLE_SPEED:
                    minSpindleSpd = Integer.valueOf(value);
                    return true;
                case MAXIMUM_SPINDLE_SPEED:
                    maxSpindleSpd = Integer.valueOf(value);
                    return true;
                case MINIMUM_SPINDLE_SPEED_OVERRIDE:
                    minSpindleSpdO = Integer.valueOf(value);
                    return true;
                case MAXIMUM_SPINDLE_SPEED_OVERRIDE:
                    maxSpindleSpdO = Integer.valueOf(value);
                    return true;
                default:
                    return false;
            }
    }
    public boolean initData(int id,long value)
    {
        return initData( id,(int) value);
    }
    public Component getView(Id viewID)
    {
        JPanel panel = new JPanel();
        switch(viewID)
        {
            case SPINDLE:
                panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS));//new GridLayout(1,2));
                JPanel p_aux1 = new JPanel(new GridBagLayout());//new GridLayout(3,1));
                //JPanel p_aux2 = new JPanel(new GridBagLayout());
                sField.setValue(spindleSpd);
                sBar.setMaximum(maxSpindleSpdO);
                sBar.setMinimum(minSpindleSpdO);
                sBar.setValue(spindleSpdO);
                sBar.setString(""+spindleSpdO+"%");
                spindleDirIcon.setIcon(
                    NewComp.getIcon(spindleDirOpt[spindleDir]));
                p_aux1.add(sField,new GridBagConstraints());
                //p_aux1.add(sBar);
                //p_aux1.add(new JPanel());
                //GridBagConstraints constraints = new GridBagConstraints();
                //p_aux2.add(sField,constraints);
                //constraints.gridx = 1;
                //p_aux2.add(spindleDirIcon,constraints);
                //panel.add(p_aux1);
                //panel.add(p_aux2);
                panel.add(sBar);
                panel.add(p_aux1);
                panel.add(spindleDirIcon);
                return panel;
            case SPINDLE_MOTION:
                panel.setLayout(new GridLayout(1,2));
                JPanel p_aux = new JPanel();
                JLabel spindleMtnLabel = NewComp.getLabel("spindleMtn","titleLabelTFrame","blue");
                spindleMtnField = NewComp.getTxtField(
                    spindleMtnOpt[spindleMtn.intValue()],
                    "textFieldTFrame");
                p_aux.add(spindleMtnField);
                panel.add(spindleMtnLabel);
                panel.add(p_aux);
                return panel;
            case SPINDLE_DIRECTION:
                panel.setLayout(new GridLayout(1,2));
                JPanel p_aux_ = new JPanel();
                JLabel spindleDirLabel = NewComp.getLabel("spindleDir","titleLabelTFrame","blue");
                spindleDirField = NewComp.getTxtField(
                    spindleDirOpt[spindleDir],
                    "textFieldTFrame");
                p_aux_.add(spindleDirField);
                panel.add(spindleDirLabel);
                panel.add(p_aux_);
                return panel;
            default:
                return null;
        }
    }
    public Component getEditor(Id editorID)
    {
        JPanel panel;
        JPanel panel_aux1;
        JPanel panel_aux2;
        JPanel panel_aux3;
        JPanel panel_aux4;
        JPanel panel_aux5;
        ButtonGroup group = new ButtonGroup();
        switch(editorID)
        {
            case SPINDLE_SPEED_OVERRIDE:
                panel = NewComp.getPanel(new BorderLayout());
                JLabel spindleSOLabel = NewComp.getLabel("spindleSpeedO","titleLabelBFrame","black");
                JSlider spindleSOSlider = NewComp.getSlider(
                    minSpindleSpdO,
                    maxSpindleSpdO,
                    spindleSpdO
                );
                if(minSpindleSpdO == maxSpindleSpdO)
                    spindleSOSlider.setEnabled(false);
                spindleSOSlider.addChangeListener( new
                    ChangeListener()
                    {
                        public void stateChanged(ChangeEvent event)
                        {
                            JSlider aux = (JSlider) event.getSource();
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE_OVERRIDE, aux.getValue());
                        }
                    }
                );
                panel_aux1 = new JPanel();
                panel_aux2 = new JPanel();
                panel_aux1.add(spindleSOLabel);
                panel_aux2.add(spindleSOSlider);
                panel.add(panel_aux1,BorderLayout.NORTH);
                panel.add(panel_aux2,BorderLayout.CENTER);
                return panel;
            case SPINDLE_DIRECTION:
                panel = NewComp.getPanel("spindleDir","titleBorderBFrame",new GridLayout(1,2));
                JRadioButton normalRB =NewComp.getRadioButton( 
                    "normal", 
                    "titleRButton", 
                    "blue",
                    spindleDirOpt[spindleDir].equals("normal"), 
                    new ActionListener()
                    {
                        public void actionPerformed(ActionEvent event)
                        {
                            //setCommandValue(KbdCmdId.CmdId.SPINDLE.getId(), KbdCmdId.CmdValue.SPINDLE_NORMAL_ROTATION.getValue());
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE, KbdCmdId.CmdValue.SPINDLE_NORMAL_ROTATION);
                        }
                    }
                );
                JRadioButton reverseRB =NewComp.getRadioButton( 
                    "reverse", 
                    "titleRButton",
                    "blue",
                    spindleDirOpt[spindleDir].equals("reverse"), 
                    new ActionListener()
                    {
                        public void actionPerformed(ActionEvent event)
                        {
                            //setCommandValue(KbdCmdId.CmdId.SPINDLE.getId(), KbdCmdId.CmdValue.SPINDLE_REVERSE_ROTATION.getValue());
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE, KbdCmdId.CmdValue.SPINDLE_REVERSE_ROTATION);
                        }
                    }
                );
                group.add(normalRB);
                group.add(reverseRB);
                panel.add(normalRB);
                panel.add(reverseRB);
                return panel;
            case SPINDLE_MOTION:
                panel = NewComp.getPanel("spindleMtn","titleBorderBFrame",new GridLayout(1,2));
                JRadioButton rotateRB = NewComp.getRadioButton( 
                    "rotate", 
                    "titleRButton", 
                    "blue",
                    spindleMtnOpt[spindleMtn].equals("rotate"), 
                    new ActionListener()
                    {
                        public void actionPerformed(ActionEvent event)
                        {
                            //setCommandValue(KbdCmdId.CmdId.SPINDLE.getId(), KbdCmdId.CmdValue.SPINDLE_START.getValue());
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE, KbdCmdId.CmdValue.SPINDLE_START);
                        }
                    }
                );
                JRadioButton stopRB = NewComp.getRadioButton( 
                    "stop", 
                    "titleRButton",
                    "blue",
                    spindleMtnOpt[spindleMtn].equals("stop"), 
                    new ActionListener()
                    {
                        public void actionPerformed(ActionEvent event)
                        {
                            //setCommandValue(KbdCmdId.CmdId.SPINDLE.getId(), KbdCmdId.CmdValue.SPINDLE_STOP.getValue());
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE, KbdCmdId.CmdValue.SPINDLE_STOP);
                        }
                    }
                );
                group.add(rotateRB);
                group.add(stopRB);
                panel.add(rotateRB);
                panel.add(stopRB);
                return panel;
            case SPINDLE_SPEED:
                panel = NewComp.getPanel(new BorderLayout());
                JLabel spindleSLabel = NewComp.getLabel("spindleSpeed","titleLabelBFrame","black");
                JSlider spindleSSlider = NewComp.getSlider(
                    minSpindleSpd,
                    maxSpindleSpd,
                    spindleSpd
                );
                if(minSpindleSpd == maxSpindleSpd)
                    spindleSSlider.setEnabled(false);
                spindleSSlider.addChangeListener( new
                    ChangeListener()
                    {
                        public void stateChanged(ChangeEvent event)
                        {
                            JSlider aux = (JSlider) event.getSource();
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE_SPEED, aux.getValue());
                        }
                    }
                );
                panel_aux1 = new JPanel();
                panel_aux2 = new JPanel();
                panel_aux1.add(spindleSLabel);
                panel_aux2.add(spindleSSlider);
                panel.add(panel_aux1, BorderLayout.NORTH);
                panel.add(panel_aux2, BorderLayout.CENTER);
                return panel;
            case SPINDLE:
                panel = new JPanel(new GridLayout(4, 2));
                JLabel minSSLabel = NewComp.getLabel("minSpindleSpeed","titleLabelBFrame","black");
                JLabel maxSSLabel = NewComp.getLabel("maxSpindleSpeed","titleLabelBFrame","black");
                JLabel maxSOLabel = NewComp.getLabel("maxSpindleOutput","titleLabelBFrame","black");
                JLabel minSSOLabel = NewComp.getLabel("minSpindleSpeedO","titleLabelBFrame","black");
                JLabel maxSSOLabel = NewComp.getLabel("maxSpindleSpeedO","titleLabelBFrame","black");
                minSSField = NewComp.getIntegerTxtField("textFieldNumBFrame");
                minSSField.setValue(minSpindleSpd);
                minSSField.getDocument().addDocumentListener(
                    new DocumentListener() 
                    {
                        public void insertUpdate(DocumentEvent event) 
                        {
                            if(changed.lastIndexOf(Id.MINIMUM_SPINDLE_SPEED) == -1)
                                changed.add(Id.MINIMUM_SPINDLE_SPEED);
                        }
                        public void removeUpdate(DocumentEvent event) 
                        {
                            if(changed.lastIndexOf(Id.MINIMUM_SPINDLE_SPEED) == -1)
                                changed.add(Id.MINIMUM_SPINDLE_SPEED);
                        }
                        public void changedUpdate(DocumentEvent event){}
                    }
                );
                maxSSField = NewComp.getIntegerTxtField("textFieldNumBFrame");
                maxSSField.setValue(maxSpindleSpd);
                maxSSField.getDocument().addDocumentListener(
                    new DocumentListener() 
                    {
                        public void insertUpdate(DocumentEvent event) 
                        {
                            if(changed.lastIndexOf(Id.MAXIMUM_SPINDLE_SPEED) == -1)
                                changed.add(Id.MAXIMUM_SPINDLE_SPEED);
                        }
                        public void removeUpdate(DocumentEvent event) 
                        {
                            if(changed.lastIndexOf(Id.MAXIMUM_SPINDLE_SPEED) == -1)
                                changed.add(Id.MAXIMUM_SPINDLE_SPEED);
                        }
                        public void changedUpdate(DocumentEvent event){}
                    }
                );
                JFormattedTextField maxSOField = NewComp.getNumberTxtField("textFieldNumBFrame");
                minSSOField = NewComp.getIntegerTxtField("textFieldNumBFrame");
                minSSOField.setValue(minSpindleSpdO);
                minSSOField.getDocument().addDocumentListener(
                    new DocumentListener() 
                    {
                        public void insertUpdate(DocumentEvent event) 
                        {
                            if(changed.lastIndexOf(Id.MINIMUM_SPINDLE_SPEED_OVERRIDE) == -1)
                                changed.add(Id.MINIMUM_SPINDLE_SPEED_OVERRIDE);
                        }
                        public void removeUpdate(DocumentEvent event) 
                        {
                            if(changed.lastIndexOf(Id.MINIMUM_SPINDLE_SPEED_OVERRIDE) == -1)
                                changed.add(Id.MINIMUM_SPINDLE_SPEED_OVERRIDE);
                        }
                        public void changedUpdate(DocumentEvent event){}
                    }
                );
                maxSSOField = NewComp.getIntegerTxtField("textFieldNumBFrame");
                maxSSOField.setValue(maxSpindleSpdO);
                maxSSOField.getDocument().addDocumentListener(
                    new DocumentListener() 
                    {
                        public void insertUpdate(DocumentEvent event) 
                        {
                            if(changed.lastIndexOf(Id.MAXIMUM_SPINDLE_SPEED_OVERRIDE) == -1)
                                changed.add(Id.MAXIMUM_SPINDLE_SPEED_OVERRIDE);
                        }
                        public void removeUpdate(DocumentEvent event) 
                        {
                            if(changed.lastIndexOf(Id.MAXIMUM_SPINDLE_SPEED_OVERRIDE) == -1)
                                changed.add(Id.MAXIMUM_SPINDLE_SPEED_OVERRIDE);
                        }
                        public void changedUpdate(DocumentEvent event){}
                    }
                );
                panel_aux1 = new JPanel(new GridBagLayout());
                panel_aux2 = new JPanel(new GridBagLayout());
                panel_aux3 = new JPanel(new GridBagLayout());
                panel_aux4 = new JPanel(new GridBagLayout());
                //panel_aux5 = new JPanel(new GridBagLayout());
                panel_aux1.add(minSSField,new GridBagConstraints());
                panel_aux2.add(maxSSField,new GridBagConstraints());
                //panel_aux3.add(maxSOField,new GridBagConstraints());
                panel_aux3.add(minSSOField,new GridBagConstraints());
                panel_aux4.add(maxSSOField,new GridBagConstraints());
                panel.add(minSSLabel);
                panel.add(panel_aux1);
                panel.add(maxSSLabel);
                panel.add(panel_aux2);
                //panel.add(maxSOLabel);
                //panel.add(panel_aux3);
                panel.add(minSSOLabel);
                panel.add(panel_aux3);
                panel.add(maxSSOLabel);
                panel.add(panel_aux4);
                return panel;
            default:
                return null;
        }
    }
    public String getDataCategoryID()
    {
        return "spindle";
    }
    public String getValue(Id dataID)
    {
        return null;
    }
    public boolean setCommandValue(int id,int value)
    {
        if(!initData( id, value))
            return false;
        switch(id)
        {
            case KbdCmdId.CmdId.SPINDLE:
                switch(value)
                {
                    case KbdCmdId.CmdValue.SPINDLE_NORMAL_ROTATION:
                        spindleDirField.setText(
                            NewComp.getString(spindleDirOpt[spindleDir]));
                        spindleDirIcon.setIcon(
                            NewComp.getIcon(spindleDirOpt[spindleDir]));
                        break;
                    case KbdCmdId.CmdValue.SPINDLE_REVERSE_ROTATION:
                        spindleDirField.setText(
                            NewComp.getString(spindleDirOpt[spindleDir]));
                        spindleDirIcon.setIcon(
                            NewComp.getIcon(spindleDirOpt[spindleDir]));
                        break;
                    case KbdCmdId.CmdValue.SPINDLE_START:
                        spindleMtnField.setText(
                            NewComp.getString(spindleMtnOpt[spindleMtn]));
                        break;
                    case KbdCmdId.CmdValue.SPINDLE_STOP:
                        spindleMtnField.setText(
                            NewComp.getString(spindleMtnOpt[spindleMtn]));
                        break;
                }
                break;
            case KbdCmdId.CmdId.SPINDLE_SPEED:
                sField.setValue(new Integer(value));
                break;
            case KbdCmdId.CmdId.SPINDLE_OVERRIDE:
                sBar.setValue(spindleSpdO);
                sBar.setString(""+spindleSpdO+"%");
                break;
        }
        return true;
    }
    public boolean setCommandValue(int id,long value)
    {
        return setCommandValue(id,(int) value);
    }
    public boolean setDataValue(int id,int value)
    {
        return false;
    }
    public boolean setDataValue(int id,long value)
    {
        return false;
    }
    public void applyChange()
    {
        Integer aux;
        while( changed.isEmpty() == false)
        {
            switch(changed.get(0))
            {
                case MINIMUM_SPINDLE_SPEED:
                    aux = Integer.valueOf(((Number)minSSField.getValue()).intValue());
                    if((aux < 0)||(aux > maxSpindleSpd))
                    {
                        minSSField.setValue(minSpindleSpd);
                        minSSField.requestFocus();
                        return;
                    }
                    else
                    {
                        if(spindleSpd < aux)
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE_SPEED, aux);
                        minSpindleSpd = aux;
                        InfoManager.addDataValue(
                            MINIMUM_SPINDLE_SPEED, 
                            minSpindleSpd
                        );
                    }
                    break;
                case MAXIMUM_SPINDLE_SPEED:
                    aux = Integer.valueOf(((Number)maxSSField.getValue()).intValue());
                    if((aux < minSpindleSpd)||(aux > MAX_UINT_16))
                    {
                        maxSSField.setValue(maxSpindleSpd);
                        maxSSField.requestFocus();
                        return;
                    }else
                    {
                        if(aux < spindleSpd)
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE_SPEED, aux);
                        maxSpindleSpd = aux;
                        InfoManager.addDataValue(
                            MAXIMUM_SPINDLE_SPEED, 
                            maxSpindleSpd
                        );
                    }
                    break;
                case MINIMUM_SPINDLE_SPEED_OVERRIDE:
                    aux = Integer.valueOf(((Number)minSSOField.getValue()).intValue());
                    if((aux < 0)||(aux > maxSpindleSpdO))
                    {
                        minSSOField.setValue(minSpindleSpdO);
                        minSSOField.requestFocus();
                        return;
                    }
                    else
                    {
                        if(spindleSpdO < aux)
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE_OVERRIDE, aux);
                        minSpindleSpdO = aux;
                        InfoManager.addDataValue(
                            MINIMUM_SPINDLE_SPEED_OVERRIDE, 
                            minSpindleSpdO
                        );
                    }
                    break;
                case MAXIMUM_SPINDLE_SPEED_OVERRIDE:
                    aux = Integer.valueOf(((Number)maxSSOField.getValue()).intValue());
                    if((aux < minSpindleSpdO)||(aux > (int)MAX_UINT_8))
                    {
                        maxSSOField.setValue(maxSpindleSpdO);
                        maxSSOField.requestFocus();
                        return;
                    }else
                    {
                        if(aux < spindleSpdO)
                            InfoManager.addCommand(KbdCmdId.CmdId.SPINDLE_OVERRIDE, aux);
                        maxSpindleSpdO = aux;
                        InfoManager.addDataValue(
                            MAXIMUM_SPINDLE_SPEED_OVERRIDE, 
                            maxSpindleSpdO
                        );
                    }
                    break;
                case OTHER:
                    break;
                default:
                    break;
            }
            changed.remove(0);
        }
    }
    public void cancelChange()
    {
        while( changed.isEmpty() == false)
        {
            switch(changed.get(0))
            {
                case MINIMUM_SPINDLE_SPEED:
                    minSSField.setValue(minSpindleSpd);
                    break;
                case MAXIMUM_SPINDLE_SPEED:
                    maxSSField.setValue(maxSpindleSpd);
                    break;
                case MINIMUM_SPINDLE_SPEED_OVERRIDE:
                    minSSOField.setValue(minSpindleSpdO);
                    break;
                case MAXIMUM_SPINDLE_SPEED_OVERRIDE:
                    maxSSOField.setValue(maxSpindleSpdO);
                    break;
                case OTHER:
                    break;
                default:
                    break;
            }
            changed.remove(0);
        }
        changed.clear();
    }
    static
    {
        spindleDir = new Integer(0);
        spindleMtn = new Integer(0);
        spindleSpdO = new Integer(100);
        minSpindleSpdO = new Integer(50);
        maxSpindleSpdO = new Integer(120);
        spindleSpd = new Integer(1500);
        minSpindleSpd = new Integer(0);
        maxSpindleSpd = new Integer(3000);
        maxSpindleOutput = new Integer(0);
        sField = NewComp.getFTF( 4, "textFieldNumTFrame");
        sBar = NewComp.getProgressBar("textBar");
        spindleDirIcon = NewComp.getLabel();
        spindleMtnField = NewComp.getTxtField("default", "textFieldTFrame");
        spindleDirField = NewComp.getTxtField("default", "textFieldTFrame");
    }
    private static final String[] spindleMtnOpt = {
        "rotate",
        "stop"
    };
    private static final String[] spindleDirOpt = {
        "normal",
        "reverse"
    };
    private static Integer spindleDir;
    private static Integer spindleMtn;
    private static Integer spindleSpdO;
    private static Integer minSpindleSpdO;
    private static Integer maxSpindleSpdO;
    private static Integer spindleSpd;
    private static Integer minSpindleSpd;
    private static Integer maxSpindleSpd;
    private static JFormattedTextField minSSField;
    private static JFormattedTextField maxSSField;
    private static JFormattedTextField maxSSOField;
    private static JFormattedTextField minSSOField;
    private static Integer maxSpindleOutput;
    private static JFormattedTextField sField;
    private static JProgressBar sBar;
    private static JLabel spindleDirIcon;
    private static JTextField spindleMtnField;
    private static JTextField spindleDirField;
}
